package com.ssy.lingxi.platform.manage.serviceimpl.content;

import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.ShelfEnum;
import com.ssy.lingxi.platform.manage.entity.content.ContentNotice;
import com.ssy.lingxi.platform.manage.entity.content.QContentNotice;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonStatusRequest;
import com.ssy.lingxi.platform.manage.model.request.content.ContentNoticePageRequest;
import com.ssy.lingxi.platform.manage.model.request.content.ContentNoticeRequest;
import com.ssy.lingxi.platform.manage.model.response.ContentNoticeResponse;
import com.ssy.lingxi.platform.manage.repository.ContentNoticeRepository;
import com.ssy.lingxi.platform.manage.service.content.IContentNoticeService;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.objects.annotations.Constructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 公告管理 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/9/17
 */
@Service
public class ContentNoticeServiceImpl implements IContentNoticeService {

    @Resource
    private ContentNoticeRepository contentNoticeRepository;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    @Override
    @ApiOperation(value = "列表")
    public Wrapper<PageData<ContentNotice>> page(ContentNoticePageRequest request) {
        QContentNotice qContentNotice = QContentNotice.contentNotice;
        JPAQuery<ContentNotice> jpaQuery = jpaQueryFactory.select(qContentNotice).from(qContentNotice);
        if (StringUtils.isNotBlank(request.getTitle())) {
            jpaQuery.where(qContentNotice.title.contains(request.getTitle()));
        }
        if (request.getColumnType() != null) {
            jpaQuery.where(qContentNotice.columnType.eq(request.getColumnType()));
        }
        if (request.getStatus() != null) {
            jpaQuery.where(qContentNotice.status.eq(request.getStatus()));
        }
        if (request.getStartTime() != null) {
            jpaQuery.where(qContentNotice.createTime.goe(request.getStartTime()));
        }
        if (request.getEndTime() != null) {
            jpaQuery.where(qContentNotice.createTime.loe(request.getEndTime()));
        }
        long totalCount = jpaQuery.fetchCount();
        List<ContentNotice> noticeList = jpaQuery.orderBy(qContentNotice.createTime.desc()).limit(request.getPageSize()).offset((long) (request.getCurrent() - 1) * request.getPageSize()).fetch();
        return Wrapper.success(new PageData<>(totalCount, noticeList));
    }

    @Override
    @ApiOperation(value = "详情")
    public Wrapper<ContentNotice> get(CommonIdRequest request) {
        ContentNotice contentNotice = contentNoticeRepository.findById(request.getId()).orElse(null);
        if (contentNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(contentNotice);
    }

    @Override
    @Transactional
    @ApiOperation(value = "新增")
    public Wrapper<Void> add(ContentNoticeRequest request, UserLoginCacheDTO user) {
        ContentNotice contentNotice = new ContentNotice();
        BeanUtils.copyProperties(request, contentNotice);
        contentNoticeRepository.saveAndFlush(contentNotice);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "修改")
    public Wrapper<Void> update(ContentNoticeRequest request, UserLoginCacheDTO user) {
        ContentNotice contentNotice = contentNoticeRepository.findById(request.getId()).orElse(null);
        if (contentNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (contentNotice.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        BeanUtils.copyProperties(request, contentNotice);
        contentNoticeRepository.saveAndFlush(contentNotice);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "上架/下架")
    public Wrapper<Void> updateStatus(CommonStatusRequest request, UserLoginCacheDTO user) {
        ContentNotice contentNotice = contentNoticeRepository.findById(request.getId()).orElse(null);
        if (contentNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        contentNotice.setStatus(request.getShelfStatus());
        contentNoticeRepository.saveAndFlush(contentNotice);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "删除")
    public Wrapper<Void> delete(CommonIdRequest request, UserLoginCacheDTO user) {
        ContentNotice contentNotice = contentNoticeRepository.findById(request.getId()).orElse(null);
        if (contentNotice == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (contentNotice.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        contentNoticeRepository.delete(contentNotice);
        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "根据栏目获取所有")
    public Wrapper<List<ContentNotice>> findAllByColumnType(Integer columnType) {
        List<ContentNotice> list = contentNoticeRepository.findAllByStatusAndColumnType(ShelfEnum.ON_SHELF.getCode(), columnType, Sort.by(Sort.Direction.DESC, "createTime"));
        return Wrapper.success(list);
    }

    @Override
    @ApiOperation(value = "获取最新公告")
    public Wrapper<PageData<ContentNotice>> findNewestNotice(PageVO pageVO) {
        QContentNotice qContentNotice = QContentNotice.contentNotice;
        JPAQuery<ContentNotice> jpaQuery = jpaQueryFactory.select(qContentNotice)
                .from(qContentNotice)
                .where(qContentNotice.status.eq(2), qContentNotice.columnType.eq(1));
        long totalCount = jpaQuery.fetchCount();
        List<ContentNotice> noticeList = jpaQuery.orderBy(qContentNotice.top.desc(), qContentNotice.createTime.desc()).fetch();
        return Wrapper.success(new PageData<>(totalCount, noticeList));
    }

    /**
     * 根据栏目获取所有(不返回context字段内容)
     *
     * @param columnType 栏目类型
     * @return 操作结果
     */
    @Override
    public Wrapper<List<ContentNoticeResponse>> findWithOutContent(Integer columnType) {
        QContentNotice qContentNotice = QContentNotice.contentNotice;
        List<ContentNoticeResponse> list = jpaQueryFactory.select(
                Projections.constructor(ContentNoticeResponse.class,
                        qContentNotice.id,
                        qContentNotice.title,
                        qContentNotice.columnType,
                        qContentNotice.top,
                        qContentNotice.status,
                        qContentNotice.createTime))
                .from(qContentNotice)
                .where(qContentNotice.status.eq(ShelfEnum.ON_SHELF.getCode()).and(qContentNotice.columnType.eq(columnType)))
                .orderBy(qContentNotice.createTime.desc()).fetch();
        return Wrapper.success(list);
    }
}
